package ligne2vie.topos.client.panels;

import ligne2vie.topos.client.SimpleMessageBox;
import ligne2vie.topos.client.gwt.proxy.MyAnchor;
import ligne2vie.topos.client.service.UserService;
import ligne2vie.topos.client.service.UserServiceAsync;
import ligne2vie.topos.shared.bo.TGoogleUser;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * The {@link LogInPanel} is designed to be displayed to replace {@link ParticipationPanel} if the user is not logged
 * in.
 * 
 * @author thuguerre
 * @since 1.0.0
 */
public class LogInPanel extends VerticalPanel {

	/**
	 * The user service to use to manage users.
	 */
	private static final UserServiceAsync userService = GWT.create(UserService.class);

	/**
	 * Default constructor.
	 */
	public LogInPanel() {

		userService.isUserLoggedIn(new IsUserLoggedIn(this));
	}

	/**
	 * The method {@link #isUserLoggedIn(Boolean)} is in charge to display the right information to the user depending
	 * he is logged in or not.
	 * 
	 * @param loggedIn
	 *            <code>true</code> if the user is logged in, <code>false</code> (or <code>null</code>) else.
	 */
	protected void isUserLoggedIn(Boolean loggedIn) {

		if (loggedIn == null || !loggedIn) {

			// --- informing the control panel, the user is not logged in

			ControlPanel.getInstance().displayLogInPanel();

			// --- display right information

			this.setHorizontalAlignment(ALIGN_CENTER);

			MyAnchor loginLink = new MyAnchor("Se connecter");
			loginLink.setEnabled(true);
			this.add(loginLink);

			loginLink.addClickHandler(new ClickHandler() {

				@Override
				public void onClick(ClickEvent event) {
					userService.createLoginURL("/", new AsyncCallback<String>() {

						@Override
						public void onSuccess(String loginURL) {
							Window.open(loginURL, "_self", "");
						}

						@Override
						public void onFailure(Throwable caught) {
							new SimpleMessageBox("Erreur...", caught.getMessage());
						}
					});
				}
			});

		} else {

			// --- creating the label which will contain the user name

			HTML label = new HTML();
			this.add(label);

			userService.getCurrentUser(new GetCurrentUser(label));

			// --- creating link allowing to log out

			MyAnchor logoutLink = new MyAnchor("Se d\u00E9connecter");
			logoutLink.setEnabled(true);
			this.add(logoutLink);
			logoutLink.addClickHandler(new ClickHandler() {

				@Override
				public void onClick(ClickEvent event) {
					userService.createLogoutURL("/", new AsyncCallback<String>() {

						@Override
						public void onSuccess(String logoutURL) {
							Window.open(logoutURL, "_self", "");
						}

						@Override
						public void onFailure(Throwable caught) {
							new SimpleMessageBox("Erreur...", caught.getMessage());
						}
					});
				}
			});
		}
	}

	/**
	 * The class {@link IsUserLoggedIn} is in charge to find if the user is logged in or not. It then give the
	 * information to the {@link LogInPanel}.
	 * 
	 * @author thuguerre
	 * @since 1.0.0
	 */
	private class IsUserLoggedIn implements AsyncCallback<Boolean> {

		private LogInPanel logInPanel = null;

		/**
		 * Default constructor.
		 * 
		 * @param logInPanel
		 *            Panel to inform once the data is back.
		 */
		protected IsUserLoggedIn(LogInPanel logInPanel) {
			this.logInPanel = logInPanel;
		}

		@Override
		public void onFailure(Throwable caught) {
			new SimpleMessageBox("Erreur...", caught.getMessage());
		}

		@Override
		public void onSuccess(Boolean result) {
			this.logInPanel.isUserLoggedIn(result);
		}
	}

	/**
	 * The class {@link GetCurrentUser} is in charge to retrieve the nickname of the current user in order to display it
	 * on the log in panel.
	 * 
	 * @author thuguerre
	 * @since 1.0.0
	 */
	private class GetCurrentUser implements AsyncCallback<TGoogleUser> {

		private HTML label;

		/**
		 * Default constructor.
		 * 
		 * @param label
		 *            Label to modify.
		 */
		protected GetCurrentUser(HTML label) {
			this.label = label;
		}

		@Override
		public void onFailure(Throwable caught) {
			label.setText("Bonjour, toi.");
		}

		@Override
		public void onSuccess(TGoogleUser result) {
			label.setText("Bonjour, " + result.getNickname() + ".");
		}

	}
}
